package cn.qiao.demo.util;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;

import freemarker.core.ParseException;
import freemarker.log.Logger;
import freemarker.template.Configuration;
import freemarker.template.MalformedTemplateNameException;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import freemarker.template.TemplateNotFoundException;

/**
 * @Description 利用FreeMarker导出Word
 * 2018年12月15日  下午10:23:40
 * @Author Huang Xiaocong
 */
public class ExportMyWord {
    
    private Logger log = Logger.getLogger(ExportMyWord.class.toString());

        private static Configuration config = null;
        static {
// Create your Configuration instance, and specify if up to what FreeMarker
// version (here 2.3.22) do you want to apply the fixes that are not 100%
// backward-compatible. See the Configuration JavaDoc for details.
            config = new Configuration(Configuration.VERSION_2_3_22);

// Specify the source where the template files come from. Here I set a
// plain directory for it, but non-file-system sources are possible too:
            try {
                config.setDirectoryForTemplateLoading(new File("G:\\java\\exercise\\project\\SpringBootDemo\\src\\main\\java\\cn\\qiao\\demo\\util\\"));
            } catch (IOException e) {
                e.printStackTrace();
            }

// Set the preferred charset template files are stored in. UTF-8 is
// a good choice in most applications:
            config.setDefaultEncoding("UTF-8");

    // Sets how errors will appear.
    // During web page *development* TemplateExceptionHandler.HTML_DEBUG_HANDLER is better.
            config.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
        }
    /**
     * FreeMarker生成Word
     * @param dataMap 数据
     * @param templateName 目标名
     * @param saveFilePath 保存文件路径的全路径名（路径+文件名）
     * @Author Huang Xiaocong 2018年12月15日 下午10:19:03
     */
    public void createWord(Map<String, Object> dataMap, String templateName, String saveFilePath) {
        //加载模板(路径)数据
        config.setClassForTemplateLoading(this.getClass(), "");
        //设置异常处理器 这样的话 即使没有属性也不会出错 如：${list.name}...不会报错
        config.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
        Template template = null;
        if(templateName.endsWith(".ftl")) {
            templateName = templateName.substring(0, templateName.indexOf(".ftl"));
        }
        try {
            template = config.getTemplate("test.ftl");
        } catch (TemplateNotFoundException e) {
            log.error("模板文件未找到", e);
            e.printStackTrace();
        } catch (MalformedTemplateNameException e) {
            log.error("模板类型不正确", e);
            e.printStackTrace();
        } catch (ParseException e) {
            log.error("解析模板出错，请检查模板格式", e);
            e.printStackTrace();
        } catch (IOException e) {
            log.error("IO读取失败", e);
            e.printStackTrace();
        }
        File outFile = new File(saveFilePath);
        if(!outFile.getParentFile().exists()) {
            outFile.getParentFile().mkdirs();
        }
        Writer out = null;
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(outFile);
        } catch (FileNotFoundException e) {
            log.error("输出文件时未找到文件", e);
            e.printStackTrace();
        }
        out = new BufferedWriter(new OutputStreamWriter(fos));
        //将模板中的预先的代码替换为数据
        try {
            template.process(dataMap, out);
        } catch (TemplateException e) {
            log.error("填充模板时异常", e);
            e.printStackTrace();
        } catch (IOException e) {
            log.error("IO读取时异常", e);
            e.printStackTrace();
        }
        log.info("由模板文件：" + templateName + ".ftl" + " 生成文件 ：" + saveFilePath + " 成功！！");
        try {
            out.close();//web项目不可关闭
        } catch (IOException e) {
            log.error("关闭Write对象出错", e);
            e.printStackTrace();
        }
    }


    public static void main(String[] args) throws IOException {
        ExportMyWord exportMyWord = new ExportMyWord();
        Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("name", "黄xx");
        dataMap.put("age", 26);
        dataMap.put("blog", "sun_flower火柴客");
        dataMap.put("email", "sun_flower@xxxx.com");
        dataMap.put("gender", "男");
        dataMap.put("telephone", "123456789101");
        dataMap.put("address", "深圳");
        dataMap.put("naturework", "全职");
        dataMap.put("industry", "IT");
        dataMap.put("aplication", "Java开发");
        dataMap.put("time", "2013年-2017年");
        dataMap.put("schoolname", "南昌大学");
        dataMap.put("education", "本科");
        dataMap.put("projectname", "电子证照xxxx");
        dataMap.put("projecttime", "2017年3月");
        dataMap.put("projectcontent", "我们除了有视、听、味、嗅、触这些外感系统之外，人类还有一个非常重要的内感系统，就是我们情绪和情感的世界。"
                + "这种感受是那样地细腻、微妙、强烈、深沉；看不见、摸不着，说不清、道不明。...");
        exportMyWord.createWord(dataMap, "cn/qiao/demo/util/test.ftl","E:\\excel\\test1.docx");
    }


}